using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Net.Configuration;

namespace Sucrose.Base
{
    public delegate void ProgressUpdateHandler(int currentTicks, int totalTicks);

    public class SucroseBaseControl
    {
        private static SucroseBaseControl instance = new SucroseBaseControl();

        public static SucroseBaseControl GetInstance()
        {
            if (instance == null)
                instance = new SucroseBaseControl();
            return instance;
        }

        public event ProgressUpdateHandler ProgressUpdates;

        private List<Course> courses = new List<Course>();


        /// <summary>
        /// Gets a list of all courses for the authenticated user
        /// </summary>
        public List<Course> Courses
        {
            get
            {
                return courses;
            }
        }

        /// <summary>
        /// Sets settings determining where support documents should be downloaded to.
        /// </summary>
        public String SupportPath
        {
            get
            {
                try
                {
                    return Settings.GetValueForKey("supportPath");
                }
                catch (KeyNotFoundException)
                {
                    String defaultPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Sucrose\\";
                    SupportPath = defaultPath;
                    return defaultPath;
                }
            }
            set
            {
                Settings.SetValueAtKey("supportPath", value);
            }
        }

        /// <summary>
        /// Sets the number of concurrent downloads
        /// </summary>
        public int ConcurrentDownloads
        {
            get
            {
                try
                {
                    return Settings.GetIntegerValueForKey("ConcurrentDownloads");
                }
                catch (KeyNotFoundException)
                {
                    ConcurrentDownloads = 2;
                    return 2;
                }
            }
            set
            {
                Settings.SetValueAtKey("ConcurrentDownloads", value);
            }
        }

        /// <summary>
        /// Initializes main controller. Mostly deals with setting up logging and settings.
        /// </summary>C:\Documents and Settings\bhenk\My Documents\Projects\sucrose4\Sucrose\SucroseBase\Exceptions\RequiresReAuthenticationException.cs
        public SucroseBaseControl()
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            SettingsSection section = (SettingsSection)config.GetSection("system.net/settings");
            section.HttpWebRequest.UseUnsafeHeaderParsing = true;
            config.Save();

            LMSInterop lms = LMSInterop.GetInstance();

            lms.ProgressUpdates  += new ProgressUpdateHandler(UpdateRelay);
            InitializeSettings();
        }

        /// <summary>
        /// Re-Authenticates the user if re-authentication is necessary. This is used because our credentials only last so long with the LMS. 
        /// If we want another LMS request after a period of time, we need to re-authenticate.
        /// </summary>
        /// <returns>If user is authenticated, true is returned. Otherwise, false is returned.</returns>
        public bool ReAuthenticate()
        {
            LMSInterop lms = LMSInterop.GetInstance();

            try
            {
                if (NeedReAuthentication())         //If we need to re-authenticate...
                    lms.Authenticate(true);  //Do so
                return true;
            }
            catch (ActionCancelledException) 
            { 
                return false;
            }
        }

        /// <summary>
        /// Determines if re-authentication is necessary.
        /// </summary>
        /// <returns>True, if re-authentication is required</returns>
        public bool NeedReAuthentication()
        {
            LMSInterop lms = LMSInterop.GetInstance();

            if (DateTime.Now.Subtract(lms.LastAuthenticated) > new TimeSpan(0, 5, 0))    //Make sure we are within the bounds of saved authentication
                return true;
            else
                return false;
        }

        /// <summary>
        /// Downloads all data from the LMS and builds local objects. This should be called immediately 
        /// after a re-authentication, although it is possible to call beforehand.
        /// </summary>
        public void ImportCourses()
        {
            LMSInterop lms = LMSInterop.GetInstance();

            courses = lms.GetCourses();
            UpdateRelay(0, 0);
        }

        /// <summary>
        /// Forwards the LMSInterop update events to Control update events.
        /// </summary>
        /// <param name="currentTicks">Numerator of percent complete fraction</param>
        /// <param name="totalTicks">Denominator of percent complete fraction</param>
        private void UpdateRelay(int currentTicks, int totalTicks)
        {
            if(ProgressUpdates != null)
                ProgressUpdates.Invoke(currentTicks, totalTicks);
        }

        /// <summary>
        /// Ensures settings gets initialized, and gets any values that will be needed right away.
        /// </summary>
        private void InitializeSettings()
        {
            string path = SupportPath;
        }
    }
}
